<?php
/**
 * Classe per la creazione automatica di un Carosello di Immagini
 *
 * IMPORTANTE: caricare nell'head i seguenti file
 *
 * <link rel="stylesheet" href="jquery.jcarousel.css" type="text/css" />
 * <link rel="stylesheet" href="jcarousel/skins/tango/skin.css" type="text/css" /> o in alternativa
 * <link rel="stylesheet" href="jcarousel/skins/ie7/skin.css" type="text/css" />
 *
 * <script src="jquery.jcarousel.js" type="text/javascript" ></script>
 *
 * @author Damiano Ciarla
 */
class JCarousel
{
	const STYLE_IE7		= "jcarousel-skin-ie7";
	const STYLE_TANGO	= "jcarousel-skin-tango";

	//--> PARAMETRI CONFIGURAZIONE CAROUSEL

	private $vertical		= false;	//--> Specifica se il carousel deve apparire orizzontale (da sinistra a destra) o verticale (dall'alto in basso)
	private $start			= 1;		//--> Indice dell'item da dove partire
	private $offset			= 1;		//--> Specifica l'indice di partenza del carousel a partire dal primo
	private $size			= null;		//--> Numero di item totali
	private $scroll			= 3;		//--> Numero di item da scrollare contemporaneamente
	private $visible		= null;		//--> Se passato calcola automaticamente larghezza e altezza degli item in base alla lunghezza del carousel e in numero di item visibili
	private $animation		= "fast";	//--> Velocita' dello scroll delle immagini
	private $easing			= null;		//--> Nome dell'effetto che si vuole usare per lo scroll
	private $auto			= 0;		//--> Specifica il numero di secondi tra uno scroll e l'altro in maniera automatica
	private $wrap			= null;

	//--> ALTRE OPZIONI

	private $widthHorizontal	= 245;
	private $heightHorizontal	= 75;
	private $widthVertical		= 75;
	private $heightVertical		= 245;
	private $widthItem			= 75;
	private $heightItem			= 75;

	/*** -------------------- *** CONFIGURAZIONE *** -------------------- ***/

	public function setVertical($vertical)
	{
		if(is_bool($vertical)) $this->vertical = $vertical;
	}

	public function setStart($start)
	{
		if(is_int($start) && $start > 0) $this->start = $start;
	}

	public function setOffset($offset)
	{
		if(is_int($offset) && $offset > 0) $this->offset = $offset;
	}

	public function setSize($size)
	{
		if(is_null($size) || (is_int($size) && $size > 0)) $this->size = $size;
	}

	public function setScroll($scroll)
	{
		if(is_int($scroll) && $scroll > 0) $this->scroll = $scroll;
	}

	public function setVisible($visible)
	{
		if(is_null($visible) || (is_int($visible) && $visible > 0)) $this->visible = $visible;
	}

	public function setAnimation($animation)
	{
		if($animation == "fast" || $animation == "slow" || (is_int($animation) && $animation >= 0)) $this->animation = $animation;
	}

	public function setEasing($easing)
	{
		$this->easing = $easing;
	}

	public function setAuto($auto)
	{
		if(is_int($auto) && $auto >= 0) $this->auto = $auto;
	}

	public function setWrap($wrap)
	{
		$this->wrap = $wrap;
	}
	
	/*** -------------------- *** OPZIONI PER LO STILE *** -------------------- ***/

	public function setWidthHorizontal($widthHorizontal)
	{
		if(is_int($widthHorizontal) && $widthHorizontal > 0) $this->widthHorizontal = $widthHorizontal;
	}

	public function setHeightHorizontal($heightHorizontal)
	{
		if(is_int($heightHorizontal) && $heightHorizontal > 0) $this->heightHorizontal = $heightHorizontal;
	}

	public function setWidthVertical($widthVertical)
	{
		if(is_int($widthVertical) && $widthVertical > 0) $this->widthVertical = $widthVertical;
	}

	public function setHeightVertical($heightVertical)
	{
		if(is_int($heightVertical) && $heightVertical > 0) $this->heightVertical = $heightVertical;
	}

	public function setWidthItem($widthItem)
	{
		if(is_int($widthItem) && $widthItem > 0) $this->widthItem = $widthItem;
	}

	public function setHeightItem($heightItem)
	{
		if(is_int($heightItem) && $heightItem > 0) $this->heightItem = $heightItem;
	}

	/**
	 * IMPORTANTE: caricare nell'head i seguenti file
	 *
	 * <link rel="stylesheet" href="jquery.jcarousel.css" type="text/css" />
	 * <link rel="stylesheet" href="jcarousel/skins/tango/skin.css" type="text/css" /> o in alternativa
	 * <link rel="stylesheet" href="jcarousel/skins/ie7/skin.css" type="text/css" />
	 *
	 * <script src="jquery.jcarousel.js" type="text/javascript"></script>
	 *
	 * Caricamento tramite AJAX delle immagini e creazione del Carousel. Lo script PHP
	 * che deve restituire i dati deve essere composto nella maniera seguente. ES:
	 *
	 * <?php
	 *
	 * $images = array(
	 *     'http://static.flickr.com/66/199481236_dc98b5abb3_s.jpg',
	 *     'http://static.flickr.com/75/199481072_b4a0d09597_s.jpg',
	 *     'http://static.flickr.com/57/199481087_33ae73a8de_s.jpg'....
	 * );
	 *
	 * $total    = count($images);
	 *
	 * header('Content-Type: text/xml');
	 *
	 * echo '<data>';
	 *
	 * echo '  <total>' . $total . '</total>';
	 *
	 * foreach ($images as $img)
	 *     echo '  <image>' . $img . '</image>';
	 *
	 * echo '</data>';
	 * ?>
	 *
	 * @param string $url				Url dove javascript fa la chiamata AJAX per recuperare i dati
	 * @param string $idContentCarousel Id dell'elemento nella pagina dove inserire il CAROUSEL
	 * @param string $createDivContent	Se true viene automaticamente creato il DIV che conterra' il Carousel altrimenti prendera' quello passato nll'$idContentCarousel
	 * @param string $classDivContent	Stile da applicare al jCarousel. Scegliere tra una delle costanti con prefisso 'STYLE_'
	 */

	public function loadFromAjax($url, $idContentCarousel, $createDivContent = false, $classDivContent = null, $useCustomStyle = false, $isImage = true)
	{
		$typeTagXml = "image";

		if(is_bool($isImage) && !$isImage) $typeTagXml = "text";

		$script  = "<script type=\"text/javascript\">";

		$script .= "function " . $idContentCarousel . "_itemLoadCallback(carousel, state)";
		$script .= "{";
		$script .= "if (carousel.has(carousel.first, carousel.last)) return;";
		$script .= "$.get(";
		$script .= "'" . $url . "',";
		$script .= "{ first: carousel.first, last: carousel.last },";
		$script .= "function(xml) { " . $idContentCarousel . "_itemAddCallback(carousel, carousel.first, carousel.last, xml); },";
		$script .= "'xml');";
		$script .= "};";

		$script .= "function " . $idContentCarousel . "_itemAddCallback(carousel, first, last, xml)";
		$script .= "{";
		$script .= "carousel.size(parseInt(jQuery('total', xml).text()));";
		$script .= "$(xml).find('" . $typeTagXml . "').each(function(i){ carousel.add(first + i, " . $idContentCarousel . "_getItemHTML($(this).text())); }); ";
		$script .= "};";

		$script .= "function " . $idContentCarousel . "_getItemHTML(content)";
		$script .= "{";

		if($isImage)
			$script .= "return '<img src=\"' + content + '\" width=\"75\" height=\"75\" alt=\"\" />';";
		else
			$script .= "return content;";

		$script .= "};";

		
		$script .= "jQuery('#" . $idContentCarousel . "').jcarousel({";
		$script .= "vertical: "		. self::printBooleanString($this->vertical)		. ",";
		$script .= "start: "		. self::printBooleanString($this->start)		. ",";
		$script .= "offset: "		. self::printBooleanString($this->offset)		. ",";
		$script .= "size: "			. self::printBooleanString($this->size)			. ",";
		$script .= "scroll: "		. self::printBooleanString($this->scroll)		. ",";
		$script .= "visible: "		. self::printBooleanString($this->visible)		. ",";
		$script .= "animation: '"	. self::printBooleanString($this->animation)	. "',";
		$script .= "easing: "		. self::printBooleanString($this->easing)		. ",";
		$script .= "auto: "			. self::printBooleanString($this->auto)			. ",";
		$script .= "wrap: "			. self::printBooleanString($this->wrap)			. ",";
		$script .= "itemLoadCallback: " . $idContentCarousel . "_itemLoadCallback";
		$script .= "});";

		$script .= "</script>";

		if($createDivContent)
		{
			if(is_null($classDivContent))
			{
				echo	"<font color='red'><strong>" .
						TD_("COMPONENTE CAROUSEL:", "components") .
						"</strong> " .
						TD_("È obbligatorio specificare una classe per l'elemento che si sta creando. Scegliere un'opzione tra le costanti dell'istanza CAROUSEL con il suffisso STYLE_", "components") .
						"</font>";

				return;
			}

			if($useCustomStyle) echo $this->getCustomStyle($classDivContent);

			echo "<div id=\"" . $idContentCarousel . "\" class=\"" . $classDivContent . "\"><ul></ul></div>";
			echo $script;
		}
		else
		{
			echo $script;
		}
	}

	/**
	 * IMPORTANTE: caricare nell'head i seguenti file
	 *
	 * <link rel="stylesheet" href="jquery.jcarousel.css" type="text/css" />
	 * <link rel="stylesheet" href="jcarousel/skins/tango/skin.css" type="text/css" /> o in alternativa
	 * <link rel="stylesheet" href="jcarousel/skins/ie7/skin.css" type="text/css" />
	 *
	 * <script src="jquery.jcarousel.js" type="text/javascript" ></script>
	 *
	 * Questo metodo prende in input un array di valori e crea automaticamente il codice
	 * necessario per implementare il componente jCarousel. L'array puo' essere composto
	 * sia da URL sia da codice HTML. L'ultimo parametro che il metodo richiede decide
	 * se il jCarousel deve essere composto da immagini o da codice.
	 *
	 * @param array $data					Array di valori da stampare
	 * @param string $idContentCarousel		Tag ID da assegnare alla lista di immagini
	 * @param stirng $classDivContent		Stile da applicare al jCarousel. Scegliere tra una delle costanti con prefisso 'STYLE_'
	 * @param boolean $isImage				Valore boolean che indica se il contenuto del jCarousel deve essere un'immagine o un html
	 * @return null							Interrompe il metodo qualora dovesse verificarsi l'errore
	 */

	public function loadFromArrayValue($data, $idContentCarousel, $classDivContent, $isImage = true)
	{
		if(is_null($classDivContent))
		{
			echo	"<font color='red'><strong>" .
					TD_("COMPONENTE CAROUSEL:", "components") .
					"</strong> " .
					TD_("È obbligatorio specificare una classe per l'elemento che si sta creando. Scegliere un'opzione tra le costanti dell'istanza CAROUSEL con il suffisso STYLE_", "components") .
					"</font>";

			return;
		}


		$html  = "<ul id=\"" . $idContentCarousel . "\" class=\"" . $classDivContent . "\">";

		foreach ($data as $content)
		{
			$html .= "<li>";

			if($isImage)
			{
				$html .= "<img src=\"" . $content . "\" border=\"0\" alt=\"\" />";
			}
			else
			{
				$html .= $content;
			}

			$html .= "</li>";
		}

		$html .= "</ul>";

		if(is_null($this->size) || $this->size > count($data)) $this->size = count($data);

		$script  = "<script type=\"text/javascript\">";

		$script .= "$('#" . $idContentCarousel . "').jcarousel({";
		$script .= "vertical: "		. self::printBooleanString($this->vertical)		. ",";
		$script .= "start: "		. self::printBooleanString($this->start)		. ",";
		$script .= "offset: "		. self::printBooleanString($this->offset)		. ",";
		$script .= "size: "			. self::printBooleanString($this->size)			. ",";
		$script .= "scroll: "		. self::printBooleanString($this->scroll)		. ",";
		$script .= "visible: "		. self::printBooleanString($this->visible)		. ",";
		$script .= "animation: '"	. self::printBooleanString($this->animation)	. "',";
		$script .= "easing: "		. self::printBooleanString($this->easing)		. ",";
		$script .= "auto: "			. self::printBooleanString($this->auto)			. ",";
		$script .= "wrap: "			. self::printBooleanString($this->wrap);
		$script .= "});";

		$script .= "</script>";

		echo $this->getCustomStyle($idContentCarousel, true) . $html . $script;
	}

	/**
	 * IMPORTANTE: caricare nell'head i seguenti file
	 *
	 * <link rel="stylesheet" href="jquery.jcarousel.css" type="text/css" />
	 * <link rel="stylesheet" href="jcarousel/skins/tango/skin.css" type="text/css" /> o in alternativa
	 * <link rel="stylesheet" href="jcarousel/skins/ie7/skin.css" type="text/css" />
	 *
	 * <script src="jquery.jcarousel.js" type="text/javascript" ></script>
	 *
	 * Questo metodo si occupa solamente di creare lo script per implementare il jCarousel
	 * partendo da una lista di immagini gia' presente nella pagina HTML
	 *
	 * @param string $idContentCarousel	Tag ID assegnato alla lista di immagini
	 * @param int $size					Numero di item presenti nel jCarousel
	 * @param boolean $return			Decide se il metodo deve stampare il codice a video o restituirlo
	 * @return string					Ritorna il codice javascript per creare il jCarousel
	 */

	public function loadFromExistingCode($idContentCarousel, $size, $return = false)
	{
		if(is_null($this->size) || $this->size > $size) $this->size = $size;

		$script  = "<script type=\"text/javascript\">";

		$script .= "$('#" . $idContentCarousel . "').jcarousel({";
		$script .= "vertical: "		. self::printBooleanString($this->vertical)		. ",";
		$script .= "start: "		. self::printBooleanString($this->start)		. ",";
		$script .= "offset: "		. self::printBooleanString($this->offset)		. ",";
		$script .= "size: "			. self::printBooleanString($this->size)			. ",";
		$script .= "scroll: "		. self::printBooleanString($this->scroll)		. ",";
		$script .= "visible: "		. self::printBooleanString($this->visible)		. ",";
		$script .= "animation: '"	. self::printBooleanString($this->animation)	. "',";
		$script .= "easing: "		. self::printBooleanString($this->easing)		. ",";
		$script .= "auto: "			. self::printBooleanString($this->auto)			. ",";
		$script .= "wrap: "			. self::printBooleanString($this->wrap);
		$script .= "});";

		$script .= "</script>";

		if($return) return $script;

		echo $script;
	}

	/*** -------------------- *** METODI INTERNI *** -------------------- ***/

	/**
	 * Questo metodo ritorna il corrispondente valore in stringa del valore passato.
	 * Ad esempio se viene passato il valore NULL il metodo ritorna la stringa 'null'.
	 * Se non viene trovato un valore o nullo o booleano viene semplicemente restituita
	 * la stringa senza alcuna modifica
	 *
	 * @param bool $value	Valore che puo' essere booleano, nullo string o int
	 * @return string		Ritorna il corrispondente valore in stringa del valore passato
	 */

	private static function printBooleanString($value)
	{
		if(is_null($value)) return "null";

		if(is_bool($value) && $value) return "true";

		if(is_bool($value) && !$value) return "false";

		return $value;
	}

	/**
	 * Questo metodo ritorna lo stile CSS castomizzato in base ai valori scelti
	 * dall'utente o impostati di default
	 *
	 * @param string $idContentCarousel	ID del div contenitore di jCarousel
	 * @param boolean $return			Speciica se il metodo deve ritornare il contenuto o stamparlo
	 * @return string					Stile CSS calcolcato
	 */

	private function getCustomStyle($idContentCarousel, $return = true)
	{
		$style = "<style>
				  #" . $idContentCarousel . " .jcarousel-container-horizontal	{ width: " . $this->widthHorizontal .	"px; }
				  #" . $idContentCarousel . " .jcarousel-container-vertical		{ width: " . $this->widthVertical .		"px;	height: " . $this->heightVertical .		"px; }
				  #" . $idContentCarousel . " .jcarousel-clip-horizontal		{ width: " . $this->widthHorizontal .	"px;	height: " . $this->heightHorizontal .	"px; }
				  #" . $idContentCarousel . " .jcarousel-clip-vertical			{ width: " . $this->widthVertical .		"px;	height: " . $this->heightVertical .		"px; }
				  #" . $idContentCarousel . " .jcarousel-item					{ width: " . $this->widthItem .			"px;	height: " . $this->heightItem .			"px; }
				  </style>";

		if($return) return $style;

		echo $style;
	}
}
?>
